// 该文件用于创建整个应用的路由
import VueRouter from "vue-router";

import About from "../pages/About";
import Home from "../pages/Home";
import Message from "../pages/Message";
import News from "../pages/News";
import Detail from "../pages/Detail";

// 下面中间的一段代码是为了防止出现多次点击同一个路由出现的错误
let originPush = VueRouter.prototype.push;
let originReplace = VueRouter.prototype.replace;
//重写push/replace
//第一个参数：告诉原来的push方法，往哪里跳转（传递哪些参数）
//第二个参数：成功的回调
//第三个参数：失败的回调
//call/apply区别
//相同点：都可以调用函数一次，都可以篡改函数的上下文(this）一次‘
//不同点：call/apply传递参数：call传递参数用逗号隔开，apply方法执行，传递数组
VueRouter.prototype.push = function (location, resolve, reject) {
  if (resolve && reject) {
    originPush.call(this, location, resolve, reject);
  } else {
    originPush.call(
      this,
      location,
      () => {},
      () => {}
    );
  }
};
VueRouter.prototype.replace = function (location, resolve, reject) {
  if (resolve && reject) {
    originReplace.call(this, location, resolve, reject);
  } else {
    originReplace.call(
      this,
      location,
      () => {},
      () => {}
    );
  }
};

const router = new VueRouter({
  routes: [
    {
      name: "about",
      path: "/about",
      component: About,
      meta: { title: "关于" },
    },
    {
      name: "home",
      path: "/home",
      component: Home,
      meta: { title: "主页" },
      children: [
        {
          name: "message",
          path: "message",
          component: Message,
          meta: { isAuth: true, title: "消息" },
          /**
           * (1) 独享路由守卫，在某一个路由里面添加路由守卫，注意只有前置没有后置!
           *     如果想要做善后处理，配合全局后置路由守卫就行，可能是后置的用的比较少
           *     用全局的完全够用
           * */ 
          beforeEnter: (to, from, next) => {
            if (to.meta.isAuth) {
              if (localStorage.getItem("school") === "atguigu") {
                next();
              } else {
                alert("学校名不对，无权限查看！");
              }
            } else {
              next();
            }
          },
          children: [
            {
              // (5) 当路由层级较多时，要写name属性，这样写地址的时候直接用name就行(必须得用to的对象形式)
              name: "detail",
              path: "detail/:id/:title",
              component: Detail,
              // (6) props给当前路由对应的组件传递参数

              // props的第一种写法，值为对象，对象中的所有数据都会以props的形式传给Detail组件
              // props:{ a:1, b:'hello'}

              // props的第二种写法，值为布尔值，若为真则会把该路由中的params参数，props的形式传给Detail组件
              // props:true

              // props的第三种写法，值为函数,接收还是用props
              // (7) 当属性的值为函数时就可以直接将属性变为函数,这就是简写形式
              // props:()=>{}
              /**
               * (8) 注意这里参数是给我$route参数的,后面用了连续解构赋值,为了不想写那么多层
               *     非常灵活,有了$route就可以任意拿属性,即可选择query还是params
               *     但是还是推荐第一种写法,好代码是简洁而且还要易懂,那样别人可能看不懂
               * (9) 注意: props只是为了接收参数时,更加简洁,和router-link发送参数不一样
               *     这里只是把参数拦截下来并用props的形式发给Detail
               * */
              props($route) {
                return { id: $route.query.id, title: $route.query.title };
              },
              // props({query:{id,title}}){
              //   return {id,title}
              // }
              // props({params:{id,title}}){
              //   return {id,title}
              // }
              meta: { title: "细节" },
            },
          ],
        },
        {
          name: "news",
          path: "news",
          component: News,
          meta: { isAuth: true, title: "新闻" },
        },
      ],
    },
  ],
});

router.beforeEach((to, from, next) => {
  // to and from are both route objects. must call `next`.
  console.log("前置路由守卫", to, from);
  // if (to.name === "message" || to.name === "news") {
  // if (to.meta.isAuth) {
  //   if (localStorage.getItem("school") === "atguigu") {
  //     next();
  //   } else {
  //     alert("学校名不对，无权限查看！");
  //   }
  // } else {
  //   next();
  // }
  next();
});

router.afterEach((to, from) => {
  console.log("后置路由守卫", to, from);
  document.title = to.meta.title || "尚硅谷";
});

export default router;
